﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Billing.DataObjects
{
    partial class BillingDataContext
    {
        private static BillingDataContext context = null;
        internal static BillingDataContext Context
        {
            get
            {
                if (context == null)
                {
                    System.Threading.Interlocked.CompareExchange<BillingDataContext>(ref context, new BillingDataContext(), null);
                }
                return context;
            }
        }

        public ISingleResult<AccountsView> AccountsSelect(int? clientID, bool filterByClientType)
        {
            return this.AccountsSelectByClientID(clientID, filterByClientType);
        }

        public ClientType GetClientTypeByID(short ID)
        {
            var aa = from t in ClientTypes
                     where t.ID == ID
                     select t;
            return GetSingleValue<ClientType>(aa);
        }

        T GetSingleValue<T>(System.Collections.Generic.IEnumerable<T> enumerable)
        {

            foreach (T t in enumerable)
            {
                return t;
            }
            return default(T);
        }

        public ClientStatuse GetClientStatusByID(short ID)
        {
            var aa = from t in ClientStatuses
                     where t.ID == ID
                     select t;
            return GetSingleValue<ClientStatuse>(aa);
        }

        public Tax GetTaxByID(short ID)
        {
            var aa = from t in Taxes
                     where t.ID == ID
                     select t;
            return GetSingleValue<Tax>(aa);
        }

        public AccountNumber GetPhoneByNumber(string number)
        {
            int? ID = null;
            AccountNumbersAdd(ref ID, number, 1, 1);
            return GetAccounNumberByID(ID.Value);
        }

        public int AccountNumbersAdd(ref int? ID, string number, short? accountNumberTypeID, short? acountNumberStatusID)
        {
            return AccountNumbersAdd(ref ID, number, accountNumberTypeID, acountNumberStatusID, false);
        }

        private AccountNumber GetAccounNumberByID(int ID)
        {
            var aa = from t in AccountNumbers
                     where t.ID == ID
                     select t;
            return GetSingleValue<AccountNumber>(aa);
        }

        public ClientsView GetClientViewByID(int ID)
        {
            var aa = from t in ClientsViews
                     where t.ID == ID
                     select t;
            return GetSingleValue<ClientsView>(aa);
        }

        public AccountNumbersView GetAccountNumberByNumber(int accountNumberTypeID, string accountNumber)
        {
            var aa = from t in AccountNumbersViews
                     where t.AccountNumberTypeID == accountNumberTypeID &&
                     t.Number.Equals(accountNumber)
                     select t;

            return GetSingleValue<AccountNumbersView>(aa);
        }

        public AccountsView GetAccountByClient(int clientID, int accNumberID)
        {
            long? ID = null;
            int? _clientID = clientID;
            int? _accNumberID = accNumberID;

            DateTime? forDate = null;


            try
            {
                AccountsValidate(ref ID, ref _clientID, ref _accNumberID, ref forDate, false);
                return GetAccountByID(ID);
            }
            catch
            {
                return null;
            }
        }

        public int AccountsValidate(ref long? ID, ref int? clientID, ref int? accNumberID, ref DateTime? forDate, bool detectClient)
        {
            return AccountsValidate(ref ID, ref clientID, ref accNumberID, ref forDate, detectClient, false);
        }

        public AccountsView GetAccountByID(long? ID)
        {
            var aa = from t in AccountsViews
                     where t.ID == ID
                     select t;

            return GetSingleValue<AccountsView>(aa);
        }

        public RentalStatuse GetRentalStatusByID(short ID)
        {
            var aa = from t in RentalStatuses
                     where t.ID == ID
                     select t;

            return GetSingleValue<RentalStatuse>(aa);
        }

        public string GetRentalStatusNameByID(short ID)
        {
            RentalStatuse r = GetRentalStatusByID(ID);

            return (r == null) ? string.Empty : r.Name;
        }

        public int ClientsAdd
            ([Parameter(Name = "ID", DbType = "Int")] ref System.Nullable<int> iD,
                   [Parameter(Name = "Key", DbType = "NVarChar(50)")] string key,
                   [Parameter(Name = "IdentificationNumber", DbType = "VarChar(20)")] string identificationNumber,
                   [Parameter(Name = "FirstName", DbType = "NVarChar(50)")] string firstName,
                   [Parameter(Name = "LastName", DbType = "NVarChar(50)")] string lastName,
                   [Parameter(Name = "Name", DbType = "NVarChar(100)")] string name,
                   [Parameter(Name = "Address", DbType = "NVarChar(100)")] string address,
                   [Parameter(Name = "Email", DbType = "VarChar(50)")] string email,
                   [Parameter(Name = "ContactInfo", DbType = "NVarChar(MAX)")] string contactInfo,
                   [Parameter(Name = "Comment", DbType = "NVarChar(MAX)")] string comment,
                   [Parameter(Name = "ClientStatusID", DbType = "SmallInt")] System.Nullable<short> clientStatusID,
                   [Parameter(Name = "ClientTypeID", DbType = "SmallInt")] System.Nullable<short> clientTypeID,
                   [Parameter(Name = "TaxID", DbType = "SmallInt")] System.Nullable<short> taxID,
                 [Parameter(DbType = "Money")] System.Nullable<decimal> contractAmount, 
                   [Parameter(DbType = "DateTime")] System.Nullable<System.DateTime> contractDate,
                   [Parameter(DbType = "NVarChar(50)")] string contractNumber,
                   [Parameter(DbType = "BIT")] bool budgeted)
        {
            return ClientsAdd(ref iD, key, identificationNumber, firstName, lastName, name, address, email, contactInfo, comment, clientStatusID, clientTypeID, taxID, contractAmount, contractDate, contractNumber, null, null, budgeted);
        }

        public int AccountsAdd(
            [Parameter(Name = "ID", DbType = "BigInt")] ref System.Nullable<long> iD,
            [Parameter(Name = "AccountNumberID", DbType = "Int")] System.Nullable<int> accountNumberID,
            [Parameter(Name = "ClientID", DbType = "Int")] System.Nullable<int> clientID,
            [Parameter(Name = "AccountTypeID", DbType = "SmallInt")] System.Nullable<short> accountTypeID,
            [Parameter(Name = "RentalStatusID", DbType = "SmallInt")] System.Nullable<short> rentalStatusID,
            [Parameter(Name = "StartDate", DbType = "SmallDateTime")] System.Nullable<System.DateTime> startDate,
            [Parameter(Name = "EndDate", DbType = "SmallDateTime")] System.Nullable<System.DateTime> endDate)
        {
            return AccountsAdd(ref iD, accountNumberID, clientID, accountTypeID, rentalStatusID, startDate, endDate, null);
        }

        public Client GetClientByID(int ID)
        {
            var aa = from t in Clients
                     where t.ID == ID
                     select t;

            return GetSingleValue<Client>(aa);
        }

        public ISingleResult<CorrectionLine> Calculate([Parameter(DbType = "BigInt")] System.Nullable<long> sourceAccountID, [Parameter(DbType = "Int")] System.Nullable<int> sourceClientID, [Parameter(DbType = "SmallInt")] System.Nullable<short> destTaxID, [Parameter(DbType = "SmallInt")] System.Nullable<short> destClientTypeID, [Parameter(DbType = "SmallDateTime")] System.Nullable<System.DateTime> from, [Parameter(DbType = "SmallDateTime")] System.Nullable<System.DateTime> to)
        {
            return this.Calculate(sourceAccountID, sourceClientID, destTaxID, destClientTypeID, from, to, false, null);
        }
    }
}
